#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
#include "wav_io.h"
#include "ff.h"

void wave_head_parse(wav_head *wav)
{
    printf("\r\n**************wav head******************\r\n");
    printf("RIFF                 :%.*s\r\n", 4, wav->riff_str);
    printf("file_length          :%ld\r\n", wav->file_length);
    printf("file_format          : %.*s\r\n", 4, wav->file_format);
    printf("fmt_str              : %.*s\r\n", 4, wav->fmt_str);
    printf("fmt_length           :%ld\r\n", wav->fmt_length);
    printf("audio_encode_mode    :%d\r\n", wav->audio_encode_mode);
    printf("audio_channel_num    :%d\r\n", wav->audio_channel_num);
    printf("audio_sample_rate    :%ld\r\n", wav->audio_sample_rate);
    printf("audio_bps            :%ld\r\n", wav->audio_bps);
    printf("audio_byte_per_point :%d\r\n", wav->audio_byte_per_point);
    printf("audio_bit            :%d\r\n", wav->audio_bit);
    printf("data_str             : %.*s\r\n", 4, wav->data_str);
    printf("audio_data_length    :%ld\r\n", wav->audio_data_length);
    printf("****************************************\r\n");
}

 
#if 0
void wavFIL_info(waveHeader_t *wavheader)
{
    printf("\r\nwavheader info:\r\n");
    printf("riff_tag: %.*s\r\n", 4, wavheader->riff_tag);
    printf("riff_length: %d\r\n", wavheader->riff_length);
    printf("format: %.*s\r\n", 4, wavheader->format);
    printf("fmt_tag: %.*s\r\n", 4, wavheader->fmt_tag);
    printf("fmt_length: %d\r\n", wavheader->fmt_length);
    printf("fmt_audio_code: %hd\r\n", wavheader->fmt_audio_code);
    printf("fmt_channel_num: %hd\r\n", wavheader->fmt_channel_num);
    printf("fmt_sample_rate: %d\r\n", wavheader->fmt_sample_rate);
    printf("fmt_byte_rate: %d\r\n", wavheader->fmt_byte_rate);
    printf("fmt_block_align: %hd\r\n", wavheader->fmt_block_align);
    printf("fmt_bit_per_sample: %hd\r\n", wavheader->fmt_bit_per_sample);
    printf("data_tag: %.*s\r\n", 4, wavheader->data_tag);
    printf("data_length: %d\r\n", wavheader->data_length);
    printf("\r\n");
}

FIL *wavFIL_read_open(const char *FILname, waveHeader_t *header)
{
    if (!header)
    {
        return NULL;
    }

    FIL *fp = NULL;

    fp = f_open(FILname, "rb");
    if (!fp)
    {
        f_printf(stderr, "read open FIL failed\n");
        return NULL;
    }

    size_t size = fread(header, sizeof(waveHeader_t), 1, fp);
    if (size != 1)
    {
        f_printf(stderr, "read FIL header failed\n");
        f_close(fp);
        return NULL;
    }

    wavFIL_info(header);

    return fp;
}


int wavFIL_read(FIL *fp, const int16_t *data, size_t size)
{
    return fread((void *)data, 1, size, fp);
}

void wavFIL_read_close(FIL *fp)
{
    if (!fp)
    {
        f_printf(stderr, "read close FIL is NULL\n");
        return;
    }

    f_close(fp);
}

int wavFIL_rewind(FIL *fp)
{
    if (!fp)
    {
        f_printf(stderr, "rewind FIL is NULL\n");
        return -1;
    }
    f_seek(fp, sizeof(waveHeader_t), SEEK_SET);
    return 0;
}

FIL *wavFIL_write_open(const char *FILname, int channels, int sample_rate)
{
    waveHeader_t header;

    strncpy(header.riff_tag, "RIFF", 4);
    header.riff_length = 0;
    strncpy(header.format, "WAVE", 4);
    strncpy(header.fmt_tag, "fmt ", 4);
    header.fmt_length = 16;
    header.fmt_audio_code = 1;
    header.fmt_channel_num = channels;
    header.fmt_sample_rate = sample_rate;
    header.fmt_bit_per_sample = WAVFIL_BIT_PER_SAMPLE;
    header.fmt_block_align = (header.fmt_bit_per_sample / 8) * header.fmt_channel_num;
    header.fmt_byte_rate = header.fmt_sample_rate * header.fmt_channel_num * (header.fmt_bit_per_sample / 8);
    strncpy(header.data_tag, "data", 4);
    header.data_length = 0;

    FIL *fp = f_open(FILname, "wb+");
    if (!fp)
    {
        f_printf(stderr, "write open FIL failed\n");
        return NULL;
    }

    f_write(&header, sizeof(header), 1, fp);

    return fp;
}

int wavFIL_write(FIL *fp, const int16_t *data, size_t size)
{
    return f_write(data, 1, size, fp);
}

void wavFIL_write_close(FIL *fp)
{
    if (!fp)
    {
        f_printf(stderr, "write close FIL is NULL\n");
        return;
    }

    int FIL_length = ftell(fp);
    int riff_length = FIL_length - sizeof(int) - (4 * sizeof(char));
    int data_length = FIL_length - sizeof(waveHeader_t);

    printf("FIL_length: %d, riff_length: %d, data_length:%d\n", FIL_length, riff_length, data_length);

    f_seek(fp, 4, SEEK_SET);
    f_write(&riff_length, sizeof(riff_length), 1, fp);

    f_seek(fp, sizeof(waveHeader_t) - sizeof(int), SEEK_SET);
    f_write(&data_length, sizeof(data_length), 1, fp);

    f_close(fp);
}

#endif